/*
* Copyright 2005-2008 Pulse Technologies. Tutti i diritti riservati.
*/
package org.obsidianrad;


import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import org.obsidianrad.server.ObsidianRad;
import org.obsidianrad.utils.ClassPathHacker;
import org.obsidianrad.utils.Constant;

/**
 * 
 * @author eliosh
 * @version $Rev: 76 $
 * @lastautorcommit $Author: eliosh $
 * @lastdatecommit $Date: 2010-01-25 16:56:59 +0100(lun, 25 gen 2010) $
 */
public class ObsidianRadStarter {


	public static void main(String[] args) throws Exception {
		File configFile = null;
		if(args.length==0){
			System.err.println("Must be run as <appname> configfile");
			return;
		}else{
			configFile = new File(args[0]);
			if(!configFile.exists()){
				System.err.println("Config file does not exist: " + configFile.getAbsolutePath());
				return;
			}
		}
		// load properties file
		Properties props = new Properties();
		props.load(new FileReader(configFile));
		
		// read properties
		boolean logEnabled = Boolean.parseBoolean(props.getProperty("log_enabled"));
		File logDir = new File(props.getProperty("log_dir"));
		File logDefinitionFile = new File(props.getProperty("log_definitionfile"));		
		File libDir = new File(props.getProperty("lib_dir"));
		File moduleDir = new File(props.getProperty("modules_dir"));
		File webDir = new File(props.getProperty("web_dir"));
		
		String beanXmlServerDefinitionPath = props.getProperty("beanxml_server_dir");
		String beanXmlModulesDefinitionPath = props.getProperty("beanxml_modules_dir");

		// check if dirs & files exists		
		if(logEnabled){
			if(!logDir.exists()){
				System.err.println("Log folder does not exist: " + logDir.getAbsolutePath());
				return;
			}
			
			if(!logDefinitionFile.exists()){
				System.err.println("Log definition file does not exist: " + logDefinitionFile.getAbsolutePath());
				return;				
			}
		}
		
		if(!libDir.exists()){
			System.err.println("Libs folder does not exist: " + libDir.getAbsolutePath());
			return;	
		}

		if(!moduleDir.exists()){
			System.err.println("Module folder does not exist: " + moduleDir.getAbsolutePath());
			return;	
		}

		// load base libs
		ClassPathHacker.addDirectory(libDir.getAbsoluteFile());
		
		// load modules
		ClassPathHacker.addDirectory(moduleDir.getAbsoluteFile());
		
		if(logEnabled){
			setLog(logDir, logDefinitionFile);
		}

		File t1 = new File(beanXmlServerDefinitionPath);
		if(t1.exists()){
			beanXmlServerDefinitionPath = t1.getAbsolutePath();
		}
		t1 = new File(beanXmlModulesDefinitionPath);
		if(t1.exists()){
			beanXmlModulesDefinitionPath = t1.getAbsolutePath();
		}
		ObsidianRad obs2 = new ObsidianRad(beanXmlServerDefinitionPath, beanXmlModulesDefinitionPath, webDir);
		obs2.start();
	}
	
	
    private static void setLog(File logDir, File logDefinitionFile) throws SecurityException, IOException{

    	// azzeriamo gli handler predefiniti
    	Handler[] handlers = Logger.getLogger("").getHandlers();
		for(int k=0; k<handlers.length; k++){
			Logger.getLogger("").removeHandler(handlers[k]);
		}
		// creiamo i nuovi handler, uno su file e uno su consolle
		FileHandler fh = new FileHandler(	logDir.getAbsolutePath() + Constant.FS + "obs2.log",
											4194304,
											10,
											true);
		ConsoleHandler ch = new ConsoleHandler();
		
		// formattatore dei logs
        SimpleFormatter sf = new SimpleFormatter();
        // assegniamo il formatter ai due log handler di 
        fh.setFormatter(sf);       
        ch.setFormatter(sf);
        
        // recuperiamo il file contenente i file di definizione dei log
		
	    Properties loggerProps = new Properties();
	    try {
	    	loggerProps.load(new FileReader(logDefinitionFile));
	        if(loggerProps.size()<0){
	        	throw new IOException("Unable to read logging file");
	        }
	        Enumeration<Object> keys = loggerProps.keys();
	        while(keys.hasMoreElements()){
	        	String packageName = (String) keys.nextElement();
	        	String logLevelStr = loggerProps.getProperty(packageName);
	        	Level logLevel = null;
	        	if(logLevelStr.toUpperCase().equals("CONFIG")){
	        		logLevel = Level.CONFIG;
	        	} else if(logLevelStr.toUpperCase().equals("FINE")){
	        		logLevel = Level.FINE;
	        	} else if(logLevelStr.toUpperCase().equals("FINER")){
	        		logLevel = Level.FINER;
	        	} else if(logLevelStr.toUpperCase().equals("FINEST")){
	        		logLevel = Level.FINEST;
	        	} else if(logLevelStr.toUpperCase().equals("INFO")){
	        		logLevel = Level.INFO;
	        	} else if(logLevelStr.toUpperCase().equals("OFF")){
	        		logLevel = Level.OFF;
	        	} else if(logLevelStr.toUpperCase().equals("SEVERE")){
	        		logLevel = Level.SEVERE;
	        	} else if(logLevelStr.toUpperCase().equals("WARNING")){
	        		logLevel = Level.WARNING;
	        	} else {
	        		logLevel = Level.ALL;
	        	}
	        	if(packageName.toUpperCase().equals("_ALL")){
	        		packageName="";
	        	}
	        	Logger.getLogger(packageName).setLevel(logLevel);
	        }
	    } catch (IOException e) {
	    	// in caso di errore nel file delle proprietà, settiamo un livello di logger default a WARNING per tutti i package
	    	Level logLevel = Level.WARNING;
	    	Logger.getLogger("").setLevel(logLevel);
	    	e.printStackTrace();
	    }
        Logger.getLogger("").addHandler(fh);
        Logger.getLogger("").addHandler(ch);
    }
}
